Ленивые вычисления
==================

.. index:: 
    ленивые вычисления
    lazy calculation



Ленивые вычисления - это задержка выполнения выражений до тех пор, пока результаты  пока не понадобятся результаты этих выражений.
Ленивое вычисление является одной из фундаментальных особенностей
некоторых языков программирования. Естественно, такая отсрочка может ускорить выполнение программ, если результаты в итоге окажутся не нужны.
Концепция, похожая на ленивое вычисление, - это поведение короткого замыкания для следующих операторов:

* || (или) оператор: Вычисление второго выражения происходит только в том случае, если первое выражение ложно.

.. code-block:: d

    if (anExpression() || mayNotBeEvaluated())
    {
    // ...
    }

Если результат anExpression() истинен, то результат ||-выражения
обязательно истинный. Поскольку нам больше не нужно вычислять второе выражение
чтобы определить результат выражения ||, второе выражение не вычисляется.

* Оператор && (и): Вычисление второго выражения происходит только в том случае, если первое истинно.

.. code-block:: d

    if (anExpression() && mayNotBeEvaluated())
    {
    // ...
    }

Если результат anExpression() равен false, то результат выражения &&
обязательно будет ложным, поэтому второе выражение не вычисляется.

* ?: (тернарный) оператор: Происходит вычисление либо первого, либо второго выражения,
  в зависимости от того, является ли условие истинным или ложным, соответственно.

.. code-block:: d

    int i = condition() ? eitherThis() : orThis();

Ленивость этих операторов сказывается не только на производительности. Иногда,
вычисление одного из выражений может быть ошибкой.
Например, проверка условия is the first letter an A, приведенная ниже, будет ошибкой когда строка пуста

.. code-block:: d

    dstring s;
    // ...
    if (s[0] == 'A')
    {
    // ...
    }

Чтобы получить доступ к первому элементу s, мы должны сначала убедиться, что в строке
имеет такой элемент. По этой причине следующая проверка условия перемещает это
потенциально ошибочное логическое выражение в правую часть оператора &&, чтобы гарантировать, что оно будет вычислено только тогда, когда это будет безопасно:

.. code-block:: d

    if ((s.length >= 1) && (s[0] == 'A'))
    {
    // ...
    }

Ленивые вычисления могут быть достигнуты с помощью указателей функций, делегатов (стр. 475),
и диапазонов (стр. 569). Мы рассмотрим их в последующих главах.
